const BaseStrategy = require('../base/BaseStrategy')

/**
 * MACD长期上涨策略
 *
 * 基于MACD指标的长期上涨趋势识别策略
 * 结合EMA、KDJ等多个指标进行综合判断
 * 支持多时间框架确认和风险控制
 */
class MacdLongUpStrategy extends BaseStrategy {
  constructor (config = {}) {
    const defaultConfig = {
      priority: 80,
      parameters: {
        // 基础MACD条件
        minMacdUpDays: 22, // 最小MACD上涨天数
        minEmaUpDays: 18, // 最小EMA上涨天数
        kdjThreshold: 0, // KDJ阈值

        // 强确认条件
        strongConfirmation: {
          macdUpDays1h: 20, // 1小时MACD上涨天数
          emaUpDays1h: 20, // 1小时EMA上涨天数
          macdUpDays4h: 20, // 4小时MACD上涨天数
          emaUpDays4h: 20 // 4小时EMA上涨天数
        },

        // 中等确认条件
        mediumConfirmation: {
          minMacdUpDays: 20, // 最小MACD上涨天数
          minEma510Days: 20, // 最小EMA5-10上涨天数
          minEma51020Days: 1, // 最小EMA5-10-20上涨天数
          minMacdUpDays1h: 2 // 1小时最小MACD上涨天数
        },

        // 长期趋势条件
        longTermTrend: {
          macdUpDaysThreshold: 30, // 长期MACD上涨阈值
          emaUpDaysThreshold: 80, // 长期EMA上涨阈值
          ema1020DaysThreshold: 128 // EMA10-20上涨阈值
        },

        // 置信度加成配置
        confidenceBonus: {
          longTermTrend: 0.2, // 长期趋势加成
          multiTimeframeConfirm: 0.3, // 多时间框架确认加成
          marketAlignment: 0.1, // 市场环境一致加成
          strongEma: 0.15, // 强EMA信号加成
          newHigh: 0.1 // 创新高加成
        },

        // 子策略权重
        subStrategyWeights: {
          STRONG_MULTI_TF: 1.0, // 强多时间框架确认
          PARTIAL_TF: 0.8, // 部分时间框架确认
          LONG_TERM: 0.9, // 长期趋势
          BASIC: 0.6, // 基础信号
          EMA_STRONG: 0.85, // 强EMA信号
          MARKET_UP_TREND: 0.75 // 市场上涨趋势
        }
      },

      riskSettings: {
        maxPosition: 0.4, // 最大仓位
        stopLoss: 0.03, // 止损
        takeProfit: 0.12, // 止盈
        maxDrawdown: 0.08 // 最大回撤
      }
    }

    super('macd_long_up', { ...defaultConfig, ...config })

    // 策略特定的统计信息
    this.strategyStats = {
      subStrategyCount: {}, // 各子策略执行次数
      avgConfidenceBySubStrategy: {}, // 各子策略平均置信度
      successRateBySubStrategy: {} // 各子策略成功率
    }
  }

  /**
   * 检查策略执行条件
   */
  checkConditions (marketData, analysisData) {
    const { analysisInfo15m, marketFlagInfo } = analysisData
    const { minMacdUpDays, minEmaUpDays } = this.config.parameters

    // 基础数据完整性检查
    if (!analysisInfo15m || !analysisInfo15m.hasFullData) {
      this.emit('debug', 'MACD策略：15分钟数据不完整')
      return false
    }

    // 基础MACD和EMA条件
    const basicMacdOk = analysisInfo15m.macdUpDays >= minMacdUpDays
    const basicEmaOk = analysisInfo15m.ema5W10A20Days >= minEmaUpDays

    if (!basicMacdOk || !basicEmaOk) {
      this.emit('debug', `MACD策略：基础条件不满足 MACD:${analysisInfo15m.macdUpDays}/${minMacdUpDays} EMA:${analysisInfo15m.ema5W10A20Days}/${minEmaUpDays}`)
      return false
    }

    // KDJ条件检查
    const kdjOk = this.checkKdjConditions(marketData, analysisData)
    if (!kdjOk) {
      this.emit('debug', 'MACD策略：KDJ条件不满足')
      return false
    }

    // 市场环境检查（可选）
    if (marketData.isMarketChaos && !this.canTradeInChaos(analysisData)) {
      this.emit('debug', 'MACD策略：市场混乱且不适合交易')
      return false
    }

    return true
  }

  /**
   * 生成交易信号
   */
  generateSignal (marketData, analysisData) {
    const subStrategyResult = this.determineSubStrategy(analysisData)
    const confidence = this.calculateConfidence(analysisData, subStrategyResult)
    const level = this.calculateSignalLevel(analysisData, confidence)
    const positionRate = this.calculatePositionRate(confidence, subStrategyResult)

    // 更新子策略统计
    this.updateSubStrategyStats(subStrategyResult.code, confidence)

    const signal = {
      type: 'BUY',
      reason: `MACD长期上涨-${subStrategyResult.name}`,
      confidence,
      positionRate,
      canReverse: true,
      level,
      metadata: {
        subStrategy: subStrategyResult.code,
        subStrategyName: subStrategyResult.name,
        conditions: subStrategyResult.conditions,
        parameters: this.getEffectiveParameters(analysisData),
        marketConditions: this.getMarketConditions(marketData, analysisData),
        timeframeAnalysis: this.getTimeframeAnalysis(analysisData)
      }
    }

    this.emit('debug', `MACD策略生成信号: ${JSON.stringify({
      subStrategy: subStrategyResult.code,
      confidence: confidence.toFixed(3),
      positionRate: positionRate.toFixed(3),
      level
    })}`)

    return signal
  }

  /**
   * 检查KDJ相关条件
   */
  checkKdjConditions (marketData, analysisData) {
    const { analysisInfo15m, marketFlagInfo } = analysisData
    const { kdjThreshold } = this.config.parameters
    const strategy = marketData.strategy || '1'

    // 基础KDJ条件
    if (analysisInfo15m.kdjDiff > kdjThreshold) {
      return true
    }

    // 市场上涨趋势中的KDJ增长
    if (marketFlagInfo.indexIfMarketUpTrend && strategy === '1' && analysisInfo15m.isKdjIncrease) {
      return true
    }

    // 多时间框架良好环境下的KDJ增长
    if (strategy === '1' &&
        marketFlagInfo.ifMarket4hMacdEmaAllGood &&
        marketFlagInfo.ifMarket1hMacdEmaAllGood &&
        analysisInfo15m.isKdjIncrease) {
      return true
    }

    return false
  }

  /**
   * 确定子策略类型
   */
  determineSubStrategy (analysisData) {
    const { analysisInfo15m, analysisInfo1h, analysisInfo4h, marketFlagInfo } = analysisData

    // 强多时间框架确认策略
    if (this.checkStrongMultiTimeframeConfirmation(analysisInfo15m, analysisInfo1h, analysisInfo4h)) {
      return {
        code: 'STRONG_MULTI_TF',
        name: '强多时间框架确认',
        conditions: [
          `15m_macd_${analysisInfo15m.macdUpDays}d`,
          `15m_ema_${analysisInfo15m.ema5W10A20Days}d`,
          `1h_macd_${analysisInfo1h.macdUpDays}d`,
          `4h_macd_${analysisInfo4h.macdUpDays}d`
        ],
        weight: this.config.parameters.subStrategyWeights.STRONG_MULTI_TF
      }
    }

    // 部分时间框架确认策略
    if (this.checkPartialTimeframeConfirmation(analysisInfo15m, analysisInfo1h)) {
      return {
        code: 'PARTIAL_TF',
        name: '部分时间框架确认',
        conditions: [
          `15m_macd_${analysisInfo15m.macdUpDays}d`,
          `15m_ema510_${analysisInfo15m.ema5A10Days}d`,
          `1h_macd_${analysisInfo1h.macdUpDays}d`
        ],
        weight: this.config.parameters.subStrategyWeights.PARTIAL_TF
      }
    }

    // 长期趋势策略
    if (this.checkLongTermTrend(analysisInfo15m, analysisInfo1h)) {
      return {
        code: 'LONG_TERM',
        name: '长期趋势确认',
        conditions: [
          `15m_macd_${analysisInfo15m.macdUpDays}d`,
          `15m_ema_${analysisInfo15m.ema5W10A20Days}d`,
          '1h_confirmation'
        ],
        weight: this.config.parameters.subStrategyWeights.LONG_TERM
      }
    }

    // 强EMA信号策略
    if (this.checkStrongEmaSignal(analysisInfo15m, analysisInfo1h)) {
      return {
        code: 'EMA_STRONG',
        name: '强EMA信号',
        conditions: [
          `15m_ema_${analysisInfo15m.ema5W10A20Days}d`,
          `1h_ema_${analysisInfo1h.ema5W10A20Days}d`
        ],
        weight: this.config.parameters.subStrategyWeights.EMA_STRONG
      }
    }

    // 市场上涨趋势策略
    if (this.checkMarketUpTrendCondition(analysisData)) {
      return {
        code: 'MARKET_UP_TREND',
        name: '市场上涨趋势',
        conditions: [
          'market_up_trend',
          `15m_ema_${analysisInfo15m.ema5W10A20Days}d`,
          `15m_macd_${analysisInfo15m.macdUpDays}d`
        ],
        weight: this.config.parameters.subStrategyWeights.MARKET_UP_TREND
      }
    }

    // 基础策略
    return {
      code: 'BASIC',
      name: '基础上涨信号',
      conditions: [
        `15m_macd_${analysisInfo15m.macdUpDays}d`,
        `15m_ema_${analysisInfo15m.ema5W10A20Days}d`,
        'kdj_positive'
      ],
      weight: this.config.parameters.subStrategyWeights.BASIC
    }
  }

  /**
   * 检查强多时间框架确认
   */
  checkStrongMultiTimeframeConfirmation (info15m, info1h, info4h) {
    const { strongConfirmation } = this.config.parameters

    const condition1h = (
      info1h.macdUpDays >= strongConfirmation.macdUpDays1h ||
      info1h.ema5W10A20Days >= strongConfirmation.emaUpDays1h
    )

    const condition4h = (
      info4h.macdUpDays >= strongConfirmation.macdUpDays4h ||
      info4h.ema5W10A20Days >= strongConfirmation.emaUpDays4h
    )

    return condition1h && condition4h
  }

  /**
   * 检查部分时间框架确认
   */
  checkPartialTimeframeConfirmation (info15m, info1h) {
    const { mediumConfirmation } = this.config.parameters

    return (
      info15m.macdUpDays >= mediumConfirmation.minMacdUpDays &&
      info15m.ema5A10Days >= mediumConfirmation.minEma510Days &&
      info15m.ema5A10A20Days >= mediumConfirmation.minEma51020Days &&
      info1h.macdUpDays >= mediumConfirmation.minMacdUpDays1h
    )
  }

  /**
   * 检查长期趋势
   */
  checkLongTermTrend (info15m, info1h) {
    const { longTermTrend } = this.config.parameters

    return (
      info15m.macdUpDays >= longTermTrend.macdUpDaysThreshold &&
      info15m.ema5W10A20Days >= 8 &&
      info1h.macd > 0
    )
  }

  /**
   * 检查强EMA信号
   */
  checkStrongEmaSignal (info15m, info1h) {
    const { longTermTrend } = this.config.parameters

    // 15分钟强EMA
    const strong15m = info15m.ema5W10A20Days >= longTermTrend.emaUpDaysThreshold

    // 1小时强EMA
    const strong1h = (
      info1h.ema5W10A20Days >= longTermTrend.emaUpDaysThreshold &&
      info1h.kdjDiff > 0
    )

    // EMA10-20长期上涨
    const longEma1020 = info15m.ema10A20Days >= longTermTrend.ema1020DaysThreshold

    return strong15m || strong1h || longEma1020
  }

  /**
   * 检查市场上涨趋势条件
   */
  checkMarketUpTrendCondition (analysisData) {
    const { marketFlagInfo, analysisInfo15m, indexFlagInfo } = analysisData

    return (
      marketFlagInfo.indexIfMarketUpTrend &&
      analysisInfo15m.ema5W10A20Days >= 8 &&
      analysisInfo15m.macdUpDays >= 30 &&
      (indexFlagInfo?.isIndexCloseNowNewHigh || false)
    )
  }

  /**
   * 计算信号置信度
   */
  calculateConfidence (analysisData, subStrategyResult) {
    let confidence = 0.5 // 基础置信度
    const { analysisInfo15m, analysisInfo1h, analysisInfo4h, marketFlagInfo, indexFlagInfo } = analysisData
    const { confidenceBonus } = this.config.parameters

    // 子策略权重加成
    confidence += (subStrategyResult.weight - 0.5)

    // 长期趋势加成
    if (analysisInfo15m.macdUpDays >= 30) {
      confidence += confidenceBonus.longTermTrend
    }

    // 多时间框架确认加成
    if (this.checkStrongMultiTimeframeConfirmation(analysisInfo15m, analysisInfo1h, analysisInfo4h)) {
      confidence += confidenceBonus.multiTimeframeConfirm
    }

    // 市场整体环境加成
    if (marketFlagInfo.ifMarket4hMacdEmaAllGood && marketFlagInfo.ifMarket1hMacdEmaAllGood) {
      confidence += confidenceBonus.marketAlignment
    }

    // 强EMA信号加成
    if (analysisInfo15m.ema5W10A20Days >= 80 || analysisInfo1h.ema5W10A20Days >= 80) {
      confidence += confidenceBonus.strongEma
    }

    // 创新高加成
    if (indexFlagInfo?.isIndexCloseNowNewHigh || indexFlagInfo?.isIndexInNewHighTrend) {
      confidence += confidenceBonus.newHigh
    }

    // MACD强度加成
    if (analysisInfo1h.macd > 0 && analysisInfo1h.ema5W10A20Days >= 25 && analysisInfo1h.kdjDiff > 0) {
      confidence += 0.1
    }

    // 特殊条件的置信度调整
    confidence = this.adjustConfidenceForSpecialConditions(confidence, analysisData)

    return Math.min(confidence, 1.0)
  }

  /**
   * 特殊条件的置信度调整
   */
  adjustConfidenceForSpecialConditions (confidence, analysisData) {
    const { analysisInfo15m, analysisInfo1h, marketFlagInfo } = analysisData

    // 如果是策略反转且不是强确认，降低置信度
    if (analysisData.strategy === '2' && confidence < 0.8) {
      confidence *= 0.8
    }

    // 如果15分钟MACD刚开始上涨且没有其他强确认，降低置信度
    if (analysisInfo15m.macdUpDays === 1 &&
        !(marketFlagInfo.ifMarket1hMacdEmaHasGood || marketFlagInfo.ifMarket15mMacdEmaHasGood)) {
      confidence *= 0.7
    }

    // 如果市场环境不明确，适度降低置信度
    if (!marketFlagInfo.ifMarket15mAllGood && !marketFlagInfo.ifMarket15mAllBad) {
      confidence *= 0.9
    }

    return confidence
  }

  /**
   * 计算信号等级
   */
  calculateSignalLevel (analysisData, confidence) {
    const { analysisInfo15m, analysisInfo1h, analysisInfo4h } = analysisData

    // 最高级别：高置信度 + 多重确认
    if (confidence >= 0.8 && this.checkStrongMultiTimeframeConfirmation(analysisInfo15m, analysisInfo1h, analysisInfo4h)) {
      return 2
    }

    // 中等级别：中等置信度或单一强确认
    if (confidence >= 0.6 || analysisInfo1h.ema5W10A20Days >= 80) {
      return 1
    }

    // 基础级别
    return 0
  }

  /**
   * 计算建议仓位比例
   */
  calculatePositionRate (confidence, subStrategyResult) {
    let baseRate = confidence * 0.8 // 基础仓位比例

    // 根据子策略类型调整
    baseRate *= subStrategyResult.weight

    // 确保在合理范围内
    return Math.min(Math.max(baseRate, 0.1), this.config.riskSettings.maxPosition)
  }

  /**
   * 获取生效参数
   */
  getEffectiveParameters (analysisData) {
    const { analysisInfo15m, analysisInfo1h, analysisInfo4h } = analysisData

    return {
      actualMacdUpDays15m: analysisInfo15m.macdUpDays,
      actualEmaUpDays15m: analysisInfo15m.ema5W10A20Days,
      actualKdjDiff15m: analysisInfo15m.kdjDiff,
      actualMacdUpDays1h: analysisInfo1h.macdUpDays,
      actualEmaUpDays1h: analysisInfo1h.ema5W10A20Days,
      actualMacdUpDays4h: analysisInfo4h.macdUpDays,
      configThresholds: {
        minMacdUpDays: this.config.parameters.minMacdUpDays,
        minEmaUpDays: this.config.parameters.minEmaUpDays,
        kdjThreshold: this.config.parameters.kdjThreshold
      }
    }
  }

  /**
   * 获取市场条件
   */
  getMarketConditions (marketData, analysisData) {
    return {
      strategy: marketData.strategy || '1',
      isMarketChaos: marketData.isMarketChaos || false,
      attack15m: marketData.attack15m || false,
      crash15m: marketData.crash15m || false,
      marketTrend: this.assessMarketTrend(analysisData.marketFlagInfo),
      volatility: marketData.volatility || 0.03
    }
  }

  /**
   * 获取时间框架分析
   */
  getTimeframeAnalysis (analysisData) {
    const { analysisInfo15m, analysisInfo1h, analysisInfo4h, analysisInfo1d } = analysisData

    return {
      '15m': {
        macdUpDays: analysisInfo15m.macdUpDays,
        emaUpDays: analysisInfo15m.ema5W10A20Days,
        kdjDiff: analysisInfo15m.kdjDiff,
        trend: analysisInfo15m.macd > 0 ? 'UP' : 'DOWN'
      },
      '1h': {
        macdUpDays: analysisInfo1h.macdUpDays,
        emaUpDays: analysisInfo1h.ema5W10A20Days,
        kdjDiff: analysisInfo1h.kdjDiff,
        trend: analysisInfo1h.macd > 0 ? 'UP' : 'DOWN'
      },
      '4h': {
        macdUpDays: analysisInfo4h.macdUpDays,
        emaUpDays: analysisInfo4h.ema5W10A20Days,
        trend: analysisInfo4h.macd > 0 ? 'UP' : 'DOWN'
      },
      '1d': {
        trend: analysisInfo1d.macd > 0 ? 'UP' : 'DOWN',
        emaUpDays: analysisInfo1d.ema5W10A20Days || 0
      }
    }
  }

  /**
   * 评估市场趋势
   */
  assessMarketTrend (marketFlagInfo) {
    if (marketFlagInfo.ifMarket15mAllGood) return 'STRONG_UP'
    if (marketFlagInfo.ifMarket15mAllBad) return 'STRONG_DOWN'
    if (marketFlagInfo.ifMarket1hMacdEmaHasGood) return 'MODERATE_UP'
    if (marketFlagInfo.ifMarket1hMacdEmaHasBad) return 'MODERATE_DOWN'
    return 'NEUTRAL'
  }

  /**
   * 检查是否可以在混乱市场中交易
   */
  canTradeInChaos (analysisData) {
    // 只有在有强确认的情况下才在混乱市场交易
    const { analysisInfo15m, analysisInfo1h, analysisInfo4h } = analysisData

    return this.checkStrongMultiTimeframeConfirmation(analysisInfo15m, analysisInfo1h, analysisInfo4h)
  }

  /**
   * 更新子策略统计
   */
  updateSubStrategyStats (subStrategyCode, confidence) {
    // 更新执行次数
    this.strategyStats.subStrategyCount[subStrategyCode] =
      (this.strategyStats.subStrategyCount[subStrategyCode] || 0) + 1

    // 更新平均置信度
    const currentAvg = this.strategyStats.avgConfidenceBySubStrategy[subStrategyCode] || 0
    const count = this.strategyStats.subStrategyCount[subStrategyCode]
    this.strategyStats.avgConfidenceBySubStrategy[subStrategyCode] =
      (currentAvg * (count - 1) + confidence) / count
  }

  /**
   * 获取策略特定统计信息
   */
  getStrategySpecificStats () {
    return {
      ...this.getStatistics(),
      subStrategyStats: this.strategyStats,
      parameters: this.config.parameters,
      riskSettings: this.config.riskSettings
    }
  }

  /**
   * 重置策略特定统计
   */
  resetStrategyStats () {
    this.strategyStats = {
      subStrategyCount: {},
      avgConfidenceBySubStrategy: {},
      successRateBySubStrategy: {}
    }
  }
}

module.exports = MacdLongUpStrategy
